接著來到本系列第二部分:如何寫
GLSL 的變數宣告與 JavaScript 差異很大:
列舉一些變數類型:
void:空
bool:布林
int:整數
float:浮點數
vec2 – 2
個浮點數組成的向量
vec3 – 3
個浮點數組成的向量
vec4 – 4
個浮點數組成的向量
bvec2 – 2
個布林組成的向量 // b 是 bool
bvec3 – 3
個布林組成的向量
bvec4 – 4
個布林組成的向量
ivec2 – 2
個整數組成的向量 // i 是 int
ivec3 – 3
個整數組成的向量
ivec4 – 4
個整數組成的向量
mat2 – 浮點數的 2X2
矩陣
mat3 – 浮點數的 3X3
矩陣
mat4 – 浮點數的 4X4
矩陣
通常 n
個向量有自己的意義,例如:
{r, g, b, a} // 可以是顏色 (colors)
{x, y, z, w} // 可以是座標 (points or normals)
{s, t, p, q} // 也可以是紋理座標 (texture coordinates)
變數的使用方法:
vec4 v = vec4(1.0, 2.0, 3.0, 1.0);
float x = v.x; //1.0
float x1 = v.r; //1.0
float x2 = v[0]; //1.0
vec3 xyz = v.xyz; //vec3(1.0,2.0,3.0)
vec3 xyz1 = vec(v[0],v[1],v[2]); //vec3(1.0,2.0,3.0)
vec3 rgb = v.rgb; //vec3(1.0,2.0,3.0)
vec2 xyzw = v.xyzw; //vec4(1.0,2.0,3.0,1.0);
vec2 rgba = v.rgba; //vec4(1.0,2.0,3.0,1.0);
回到 Shadertoy 的程式碼:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
// Time varying pixel color
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
// Output to screen
fragColor = vec4(col,1.0);
}
已可閱讀程式碼,但還不提上色的原理:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord/iResolution.xy;
}
fragCoord 是一個 vec2
的輸入,而 iResolution 是 shadertoy 內建的 input
(uniform vec3 iResolution)
iResolution 是
vec3
,
為了讓vec2
的 uv 不出錯,fragCoord(vec2
) 需與float
或是vec2
運算
fragCoord/iResolution.xy
; 等同於
fragCoord/vec2
(iResolution.x
, iResolution.y
);
uv 是
vec2
,因此可以用uv.x
跟uv.y
來取值
vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
3
個浮點數組成的向量,在運算的時候也必須使用 3
個浮點數做運算uv.
xyx
等同於 vec3(uv.x
, uv.y
, uv.x
)
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
fragColor = vec4(col,1.0);
}
輸出的 fragColor 是 vec4
,需要 4
個浮點數
col 是 vec3
,放到 vec4
時要補上最後一個值
踩過覺得比較特別的是 float
與 int
float 一定要有小數點,而 int 一定不能有小數點
float a1=1.0; // 沒問題,這是浮點數
float a2=1.; // 沒問題,後面有一個點
float a3=1; // 有問題,不能是整數
int a4 = 1;
float b1 = float(a4); // 轉到正確的型別即可
Storage Qualifiers 是在一些變數前會看到的字:
// Storage Qualifiers 會在變數型別的前面:
attribute vec2 aPosition;
varying vec2 vUv;
uniform vec2 texelSize;
這些是另一些看不太懂的東西,
需要配著 WebGL Pipeline 看
在此,我們更專注在 vertex shader 與 fragment shader、箭頭方向
也因為 Storage Qualifiers 的特性,
JavaScript 實際上能控制或帶進 Shader 的只有
attribute 與 uniform 兩種參數
不用,Shader 自己用的時候就不用